﻿using System;
using System.Collections.Generic;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using CAION2.Classes;
using CAION2.Commands;
using CAION2.Helpers;
using CAION2.Models;
using CAION2.Properties;
using CAION2.Views;
using FirstFloor.ModernUI.Windows.Controls;

namespace CAION2.ViewModels
{
    using System.IO;
    using System.Linq;
    using System.Windows;

    public class ItemPlaceViewModel : ViewModelBase
    {
        public enum EquipmentSlots
        {
            None,
            Foot,
            Glove,
            Head,
            Leg,
            Main,
            //MainOrSub,
            Neck,
            RightOrLeftEar,
            RightOrLeftFinger,
            Shoulder,
            Sub,
            Torso,
            Waist,
            Wing,
            Armsfused
        }

        #region Vars

        private ItemCardViewModel card;
        private BitmapImage icon;
        private BitmapImage background;
        private bool isEnabled;
        private EquipmentSlots slot;
        private string selectedGameClass;
        private byte currentCharacterLevel;
        private string translate;
        private string slotName;
        private Single opacity;
        private SolidColorBrush redBackground;
        private Visibility visible;
        private string[] masterItem;

        #endregion
        
        #region Properties
        
        public BitmapImage Icon
        {
            get { return icon; }
            private set
            {
                if (Equals(icon, value)) return;
                icon = value;

                OnPropertyChanged("Icon");
            }
        }

        public BitmapImage Background
        {
            get { return background; }
            private set
            {
                if (Equals(background, value)) return;
                background = value;

                OnPropertyChanged("Background");
            }
        }

        public bool IsEnabled
        {
            get { return isEnabled; }
            set
            {
                isEnabled = value;

                OnPropertyChanged("IsEnabled");

                Opacity = !IsEnabled ? 0.3f : 1;
            }
        }

        public EquipmentSlots Slot
        {
            get { return slot; }
            private set
            {
                if (Equals(slot, value)) return;
                slot = value;
            }
        }

        public string Translate
        {
            get { return translate; }
            set
            {
                if (Equals(translate, value)) return;
                translate = value;

                OnPropertyChanged("Translate");
            }
        }

        public string SlotName
        {
            get { return slotName; }
            private set
            {
                if (Equals(slotName, value)) return;
                slotName = value;

                OnPropertyChanged("SlotName");
            }
        }

        public ItemCardViewModel Card
        {
            get { return card; }
            private set
            {
                if (Equals(card, value)) return;
                card = value;
            }
        }

        public Single Opacity
        {
            get { return opacity; }
            private set
            {
                if (Equals(opacity, value)) return;
                opacity = value;

                OnPropertyChanged("Opacity");
            }
        }

        public SolidColorBrush RedBackground
        {
            get { return redBackground; }
            private set
            {
                if (Equals(redBackground, value)) return;
                redBackground = value;

                OnPropertyChanged("RedBackground");
            }
        }

        public byte Index { get; private set; }

        public Visibility Visible
        {
            get { return visible; }
            set
            {
                if (Equals(visible, value)) return;
                visible = value;

                OnPropertyChanged("Visible");
            }
        }

        #endregion
        
        #region Commands

        public RelayCommand GetItemForPlaceCommand { get; private set; }
        public RelayCommand OpenPlaceCommand { get; private set; }
        public RelayCommand DeletePlaceCommand { get; private set; }
        
        #endregion


        public ItemPlaceViewModel()
        {
            WireCommands();

            IsEnabled = true;
            Card = new ItemCardViewModel(Index);
            RedBackground = new SolidColorBrush(Colors.Transparent);
        }

        public ItemPlaceViewModel(byte index, EquipmentSlots slot, bool isRight = true) : this()
        {
            Index = index;
            Slot = slot;
            Visible = Visibility.Visible;

            switch (Slot)
            {
                case EquipmentSlots.Main:
                    Background = new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/Slot_Main.png", UriKind.Absolute));
                    Translate = Resources.Slot_Main;
                    break;
                case EquipmentSlots.Sub:
                    Background = new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/Slot_Sub.png", UriKind.Absolute));
                    Translate = Resources.Slot_Sub;
                    break;
                case EquipmentSlots.Wing:
                    Background = new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/Slot_Wing.png", UriKind.Absolute));
                    Translate = Resources.Slot_Wing;
                    break;
                case EquipmentSlots.Head:
                    Background = new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/Slot_Head.png", UriKind.Absolute));
                    Translate = Resources.Slot_Head;
                    break;
                case EquipmentSlots.RightOrLeftEar:
                    if (isRight)
                    {
                        Background = new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/Slot_RightEar.png", UriKind.Absolute));
                        Translate = Resources.Slot_RightEar;
                    }
                    else
                    {
                        Background = new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/Slot_LeftEar.png", UriKind.Absolute));
                        Translate = Resources.Slot_LeftEar;
                    }
                    break;
                case EquipmentSlots.RightOrLeftFinger:
                    if (isRight)
                    {
                        Background = new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/Slot_RightFinger.png", UriKind.Absolute));
                        Translate = Resources.Slot_RightFinger;
                    }
                    else
                    {
                        Background = new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/Slot_LeftFinger.png", UriKind.Absolute));
                        Translate = Resources.Slot_LeftFinger;
                    }
                    break;
                case EquipmentSlots.Torso:
                    Background = new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/Slot_Torso.png", UriKind.Absolute));
                    Translate = Resources.Slot_Torso;
                    break;
                case EquipmentSlots.Leg:
                    Background = new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/Slot_Leg.png", UriKind.Absolute));
                    Translate = Resources.Slot_Leg;
                    break;
                case EquipmentSlots.Foot:
                    Background = new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/Slot_Foot.png", UriKind.Absolute));
                    Translate = Resources.Slot_Foot;
                    break;
                case EquipmentSlots.Shoulder:
                    Background = new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/Slot_Shoulder.png", UriKind.Absolute));
                    Translate = Resources.Slot_Shoulder;
                    break;
                case EquipmentSlots.Glove:
                    Background = new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/Slot_Glove.png", UriKind.Absolute));
                    Translate = Resources.Slot_Glove;
                    break;
                case EquipmentSlots.Waist:
                    Background = new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/Slot_Waist.png", UriKind.Absolute));
                    Translate = Resources.Slot_Waist;
                    break;
                case EquipmentSlots.Neck:
                    Background = new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/Slot_Neck.png", UriKind.Absolute));
                    Translate = Resources.Slot_Neck;
                    break;
                case EquipmentSlots.Armsfused:
                    Background = new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/Slot_Armsfused.png", UriKind.Absolute));
                    Translate = Resources.Slot_Armsfused;
                    Visible = Visibility.Collapsed;
                    break;
            }

            SlotName = Translate;

            SetMediators();
        }

        private void WireCommands()
        {
            GetItemForPlaceCommand = new RelayCommand(SelectNewItem) { IsEnabled = true };
            OpenPlaceCommand = new RelayCommand(OpenPlace) { IsEnabled = true };
            DeletePlaceCommand = new RelayCommand(DeletePlace) { IsEnabled = false };
        }

        private void SetMediators()
        {
            Mediator.Instance.Register(o =>
            {
                selectedGameClass = (String)o;
            }, Messages.StatsGameClassSend);

            Mediator.Instance.Register(o =>
            {
                currentCharacterLevel = (byte)o;
            }, Messages.StatsCharacterLevelSend);
            
            if (Slot == EquipmentSlots.Sub)
            {
                Mediator.Instance.Register(o => SetSubSlot((BitmapImage) o), Messages.MainSlotChange);
            }

            if (Slot == EquipmentSlots.Armsfused)
            {
                Mediator.Instance.Register(o => SetArmsfusionSlot((string[])o), Messages.SetArmsfusion);
            }

            if (Slot == EquipmentSlots.Main)
            {
                Mediator.Instance.Register(o => SetArmsfusionInMain((ItemCardViewModel)o), Messages.ArmsfusionSlotChange);
            }
        }
        
        private void OpenPlace()
        {
            Mediator.Instance.NotifyColleagues(Messages.ShowCard, this);
        }

        private void SelectNewItem()
        {
            if (string.IsNullOrEmpty(selectedGameClass)) return;

            UiServices.SetBusyState();
            
            SelectItemPage si = new SelectItemPage();
            SelectItemDialogViewModel sivm = (SelectItemDialogViewModel)si.DataContext;

            ModernDialog md = new ModernDialog { Content = si, Title = Resources.Status_SelectItemDialogTitle };

            sivm.GameClass = selectedGameClass;
            sivm.CharacterLevel = currentCharacterLevel;
            sivm.MasterItem = masterItem;
            sivm.Slot = Slot;
            
            md.MaxWidth = 1000;
            md.MaxHeight = 700;
            md.Buttons = new[] { md.OkButton, md.CancelButton };
            md.ShowDialog();

            if (md.GetDialogResult == MessageBoxResult.Cancel || sivm.Card.Item == null) return;
            
            DeletePlace();

            Card = sivm.Card;
            if (Slot == EquipmentSlots.Armsfused)
            {
                Card.IsArmsfusionItem = true;
                Card.LoadCard();
            }
            Card.PlaceIndex = Index;
            Card.SendAllStats();

            Update();
            GetMainSlotWeaponType();

            OpenPlace();

            string[] info = { Card.Item["name"].ToString(), Card.Item.Table.TableName };
            Mediator.Instance.NotifyColleagues(Messages.ItemSetAddItem, info);
           
            if (Slot == EquipmentSlots.Armsfused)
            {
                Card.IsArmsfusionItem = true;
                Mediator.Instance.NotifyColleagues(Messages.ArmsfusionSlotChange, Card);
            }
            
            ClassConfiguration.SetBoolGroup("SelectItemQualityFilter", sivm.QualityFilter);
        }
        
        public void DeletePlace()
        {
            if (Card.Item != null)
            {
                string[] info = { Card.Item["name"].ToString() };
                Mediator.Instance.NotifyColleagues(Messages.ItemSetDelItem, info);
            }

            Card = new ItemCardViewModel(Index);
            Icon = new BitmapImage();
            Translate = SlotName;
            RedBackground = new SolidColorBrush(Colors.Transparent);

            DeletePlaceCommand.IsEnabled = false;

            if (Slot == EquipmentSlots.Main)
            {
                Mediator.Instance.NotifyColleagues(Messages.SetArmsfusion, null);
            }

            if (Slot == EquipmentSlots.Armsfused)
            {
                Mediator.Instance.NotifyColleagues(Messages.ArmsfusionSlotChange, null);
            }

            Card.SendAllStats();
            OpenPlace();
            GetMainSlotWeaponType();
        }

        public void Update()
        {
            if (Card.Item == null) return;

            Icon = File.Exists(DataModel.IconsDirectory + Card.Item["icon_name"] + ".png") 
                ? new BitmapImage(new Uri(DataModel.IconsDirectory + Card.Item["icon_name"] + ".png", UriKind.RelativeOrAbsolute)) 
                : new BitmapImage(new Uri("pack://application:,,,/CAION2;component/UI2/IconSlot.png", UriKind.Absolute));
            
            Translate = Card.Item["translate" + DataModel.EngFix].ToString();
            DeletePlaceCommand.IsEnabled = true;
        }
        
        private void SetSubSlot(BitmapImage mainIcon)
        {
            if (selectedGameClass == null) return;

            if (mainIcon == null || mainIcon.UriSource == null)
            {
                IsEnabled = ClassGameClass.GetEnableForSubSlotPlace(selectedGameClass);
            }
            else
            {
                IsEnabled = false;
            }
            
            if (!IsEnabled)
            {
                DeletePlace();
                Icon = mainIcon;
            }
            else
            {
                if (Card.Item == null) Icon = null;
            }
        }

        public void GetMainSlotWeaponType()
        {
            if (Slot != EquipmentSlots.Main) return;

            BitmapImage subIcon = new BitmapImage();
            string[] masterItemSet = null;
            
            if (Card.Item != null)
            {
                string wType = Card.Item["weapon_type"].ToString();
                if (wType.Contains("2h") || wType == "bow")
                {
                    subIcon = Icon;
                    masterItemSet = new[] { wType, Card.Item["level"].ToString(), "TRUE" };
                }
            }
            
            Mediator.Instance.NotifyColleagues(Messages.MainSlotChange, subIcon);
            Mediator.Instance.NotifyColleagues(Messages.SetArmsfusion, masterItemSet);
        }

        public void SetRedBackground(byte newLevel, string newClass)
        {
            bool[] isOn = new bool[2];
            isOn[0] = false;
            isOn[1] = false;

            if (Card.Item != null)
            {
                if (newLevel < Convert.ToByte(Card.Item["level"])) isOn[0] = true;
                
                string weaponType = "";
                if (Card.Item.Table.Columns.Contains("weapon_type"))
                    weaponType = Card.Item["weapon_type"].ToString();

                string armorType = "";
                if (Card.Item.Table.Columns.Contains("armor_type"))
                    armorType = Card.Item["armor_type"].ToString();

                isOn[1] = ClassGameClass.CheckItemForSlot(newClass, Slot, weaponType, armorType, Card.Item["name"].ToString().Substring(0,7));
            }
            
            RedBackground = isOn[0] || isOn[1] ? new SolidColorBrush(ClassConfiguration.RedColor) : new SolidColorBrush(Colors.Transparent);

            Mediator.Instance.NotifyColleagues(Messages.CardCorrectCheck, new KeyValuePair<byte, bool>(Index, !isOn[0] && !isOn[1]));

            GetMainSlotWeaponType();
        }

        private void SetArmsfusionSlot(string[] masterItemSet)
        {
            if (masterItemSet == null || !masterItemSet.Any())
            {
                Visible = Visibility.Collapsed;
                DeletePlace();
                return;
            }

            if (masterItemSet[2] == "TRUE") Visible = Visibility.Visible;
            masterItem = masterItemSet;
        }

        public void SetArmsfusionInMain(ItemCardViewModel armsfusionCard)
        {
            if (Slot != EquipmentSlots.Main) return;

            Card.LoadArmsfusionCard(armsfusionCard);
            Card.SendAllStats();
            OpenPlace();
        }
    }
}
